package org.springside.examples.miniweb.web.report;

import java.beans.BeanInfo;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.util.ArrayList;
import java.util.Collections;

import javax.persistence.Transient;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.jsp.JspTagException;

import org.apache.shiro.SecurityUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springside.examples.miniweb.entity.report.AssignedReport;
import org.springside.examples.miniweb.entity.report.ColdPumpReport;
import org.springside.examples.miniweb.entity.report.CompressorReport;
import org.springside.examples.miniweb.service.account.AccountManager;
import org.springside.examples.miniweb.service.report.ColdPumpReportManager;
import org.springside.examples.miniweb.service.report.CompReportManager;

@Controller
@RequestMapping(value = "/process")
public class ProcessController extends ReportController<AssignedReport> {

	private ColdPumpReportManager<ColdPumpReport> coldManager;

	private CompReportManager<CompressorReport> comManager;

	private AccountManager accountManager;

	/**
	 * @param manager
	 *            the manager to set
	 */
	@Autowired
	public void setColdManager(ColdPumpReportManager<ColdPumpReport> coldManager) {
		this.coldManager = coldManager;
	}

	/**
	 * @param manager
	 *            the manager to set
	 */
	@Autowired
	public void setComManager(CompReportManager<CompressorReport> comManager) {
		this.comManager = comManager;
	}

	@RequestMapping(value = { "list", "" })
	public String list(Model model) throws JspTagException {
		String userName = getPrincipalProperty(SecurityUtils.getSubject().getPrincipal(), "name");
		ArrayList<AssignedReport> reports = new ArrayList<AssignedReport>();
		reports.addAll(coldManager.getReportByUserName(userName));
		reports.addAll(comManager.getReportByUserName(userName));
		Collections.sort(reports);
		
		ArrayList<AssignedReport> finishReports = new ArrayList<AssignedReport>();
		ArrayList<AssignedReport> unfinishReports = new ArrayList<AssignedReport>();
		for (AssignedReport assignedReport : reports) {
			if(assignedReport.getStatus().equals("finish")){
				finishReports.add(assignedReport);
			}else{
				unfinishReports.add(assignedReport);
			}
		}
		
		initListPage(model);
		model.addAttribute("finishReports",finishReports.subList(0, finishReports.size() > 5 ? 5 : finishReports.size()));
		model.addAttribute("unfinishReports",unfinishReports);
		return "account/processList";
	}

	@RequestMapping(value = { "leadto/{reportId}" })
	public String leadto(@PathVariable("reportId") String reportId, Model model) throws JspTagException {
		if (reportId.startsWith("COL")) {
			return "redirect:/report/cold/update/" + reportId.substring(3);
		}

		if (reportId.startsWith("COM")) {
			return "redirect:/report/comp/update/" + reportId.substring(3);
		}
		return list(model);
	}

	
	/**
	 * @param model
	 */
	private void initListPage(Model model) {
		model.addAttribute("customers", accountManager.getAllUser());
		model.addAttribute("users", accountManager.getAllUser());
	}

	@Autowired
	public void setAccountManager(AccountManager accountManager) {
		this.accountManager = accountManager;
	}
	
	@Transient
	 private String getPrincipalProperty(Object principal, String property) throws JspTagException {
	        String strValue = null;

	        try {
	            BeanInfo bi = Introspector.getBeanInfo(principal.getClass());

	            // Loop through the properties to get the string value of the specified property
	            boolean foundProperty = false;
	            for (PropertyDescriptor pd : bi.getPropertyDescriptors()) {
	                if (pd.getName().equals(property)) {
	                    Object value = pd.getReadMethod().invoke(principal, (Object[]) null);
	                    strValue = String.valueOf(value);
	                    foundProperty = true;
	                    break;
	                }
	            }

	            if (!foundProperty) {
	                final String message = "Property [" + property + "] not found in principal of type [" + principal.getClass().getName() + "]";
	                throw new JspTagException(message);
	            }

	        } catch (Exception e) {
	            final String message = "Error reading property [" + property + "] from principal of type [" + principal.getClass().getName() + "]";
	            throw new JspTagException(message, e);
	        }

	        return strValue;
	    }
	
	@RequestMapping(value = "exportAllExcel")
	public String exportAllExcel(Model model, HttpServletRequest request ) throws JspTagException {
		String userName = getPrincipalProperty(SecurityUtils.getSubject().getPrincipal(), "name");
		ArrayList<AssignedReport> reports = new ArrayList<AssignedReport>();
		reports.addAll(coldManager.getReportByUserName(userName));
		reports.addAll(comManager.getReportByUserName(userName));
		Collections.sort(reports);
		
		ArrayList<AssignedReport> finishReports = new ArrayList<AssignedReport>();
		ArrayList<AssignedReport> unfinishReports = new ArrayList<AssignedReport>();
		for (AssignedReport assignedReport : reports) {
			if(assignedReport.getStatus().equals("finish")){
				finishReports.add(assignedReport);
			}else{
				unfinishReports.add(assignedReport);
			}
		}
		model.addAttribute("ProcessReport", unfinishReports);
		return "processExcel";
	}

}
